package com.yvdelx.cyclowomen.activity.adapter;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;

import com.jjoe64.graphview.GraphViewDataInterface;
import com.jjoe64.graphview.GraphViewSeries;
import com.jjoe64.graphview.LineGraphView;
import com.yvdelx.cyclowomen.utility.DateUtility;

/**
 * Adapter to draw lines of the graphic activity
 */
public class LineGraphViewAdapter extends LineGraphView {

    private final Paint paintBackground;
    private boolean drawBackground;
    private boolean drawDataPoints;
    private float dataPointsRadius = 10f;

    @SuppressWarnings("unused")
    public LineGraphViewAdapter(Context context, AttributeSet attrs) {
        super(context, attrs);

        paintBackground = new Paint();
        paintBackground.setColor(Color.rgb(20, 40, 60));
        paintBackground.setStrokeWidth(4);
        paintBackground.setAlpha(128);
    }

    public LineGraphViewAdapter(Context context, String title) {
        super(context, title);

        paintBackground = new Paint();
        paintBackground.setColor(Color.rgb(20, 40, 60));
        paintBackground.setStrokeWidth(4);
        paintBackground.setAlpha(128);
    }

    @Override
    public void drawSeries(Canvas canvas, GraphViewDataInterface[] values,
                           float graphWidth, float graphHeight,
                           float border, double minX,
                           double minY, double diffX,
                           double diffY, float horStart,
                           GraphViewSeries.GraphViewSeriesStyle style) {

        boolean drawTextPoint = ((GraphViewSeriesStyleAdapter)style).isDrawValueXOnPoint();

        float highPoint = getHighPoint(values);

        // draw background
        double lastEndY;
        double lastEndX;

        // draw data
        paint.setStrokeWidth(style.thickness);
        paint.setColor(style.color);


        Path bgPath = null;
        if (drawBackground) {
            bgPath = new Path();
        }

        lastEndY = 0;
        lastEndX = 0;
        float firstX = 0;
        boolean isFirstPoint = true;
        for (int i = 0; i < values.length; i++) {
            double valY = values[i].getY() - minY;
            double ratY = valY / diffY;
            double y = graphHeight * ratY;

            double valX = values[i].getX() - minX;
            double ratX = valX / diffX;
            double x = graphWidth * ratX;

            if (i > 0) {
                float startX = (float) lastEndX + (horStart + 1);
                float startY = (float) (border - lastEndY) + graphHeight;
                float endX = (float) x + (horStart + 1);
                float endY = (float) (border - y) + graphHeight;

                // draw data point
                if (drawDataPoints && drawTextPoint) {
                    canvas.drawCircle(startX, startY, dataPointsRadius, paint);
                    String dateToString = DateUtility.dateToString((long) values[i].getX(),"dd/MM");
                    float pointX;
                    float pointY;
                    if(isFirstPoint){

                        // Create first point
                        canvas.drawText(DateUtility.dateToString((long) values[0].getX(),"dd/MM"),
                                startX + 4*dataPointsRadius,
                                startY - 2*dataPointsRadius ,paint);

                        // create second point
                        pointX = endX;
                        pointY = endY - 2*dataPointsRadius;
                        isFirstPoint = false;
                    } else {
                        if(i == (values.length - 1)){ // last point of the graph
                            pointX = endX - 4*dataPointsRadius;
                            pointY = endY - 2*dataPointsRadius;
                        } else {
                            pointX = endX;
                            pointY = endY - 2*dataPointsRadius;
                        }

                        if(highPoint <= values[i].getY())
                            pointY = endY + 4*dataPointsRadius;
                    }
                    canvas.drawText(dateToString, pointX, pointY, paint);
                }

                canvas.drawLine(startX, startY, endX, endY, paint);
                if (bgPath != null) {
                    if (i==1) {
                        firstX = startX;
                        bgPath.moveTo(startX, startY);
                    }
                    bgPath.lineTo(endX, endY);
                }
            }
            lastEndY = y;
            lastEndX = x;
        }

        if (bgPath != null) {
            // end / close path
            bgPath.lineTo((float) lastEndX, graphHeight + border);
            bgPath.lineTo(firstX, graphHeight + border);
            bgPath.close();
            canvas.drawPath(bgPath, paintBackground);
        }
    }

    /**
     * Return the high point of the series in param
     * @param values GraphViewDataInterface[]
     * @return Float
     */
    private float getHighPoint(GraphViewDataInterface[] values) {
        float result = 0;
        for (GraphViewDataInterface value : values) {
            double y = value.getY();
            if (y > result)
                result = (float) y;

        }
        return result;
    }

    /**
     * Return the background color
     * @return Integer
     */
    public int getBackgroundColor() {
        return paintBackground.getColor();
    }

    /**
     * Return the circumference of the circle that represent the data point
     * @return Float
     */
    public float getDataPointsRadius() {
        return dataPointsRadius;
    }

    /**
     * Return "true" if the background must be draw
     * @return Boolean
     */
    public boolean getDrawBackground() {
        return drawBackground;
    }

    /**
     * Return "true" if the data points must be draw.
     * @return Boolean
     */
    public boolean getDrawDataPoints() {
        return drawDataPoints;
    }

    /**
     * sets the background color for the series.
     * This is not the background color of the whole graph.
     * @see #setDrawBackground(boolean)
     */
    @Override
    public void setBackgroundColor(int color) {
        paintBackground.setColor(color);
    }

    /**
     * sets the radius of the circles at the data points.
     * @see #setDrawDataPoints(boolean)
     * @param dataPointsRadius Float
     */
    public void setDataPointsRadius(float dataPointsRadius) {
        this.dataPointsRadius = dataPointsRadius;
    }

    /**
     * @param drawBackground true for a light blue background under the graph line
     * @see #setBackgroundColor(int)
     */
    public void setDrawBackground(boolean drawBackground) {
        this.drawBackground = drawBackground;
    }

    /**
     * You can set the flag to let the GraphView draw circles at the data points
     * @see #setDataPointsRadius(float)
     * @param drawDataPoints boolean
     */
    public void setDrawDataPoints(boolean drawDataPoints) {
        this.drawDataPoints = drawDataPoints;
    }

}
